Android Camera2 简介

您所在的位置:网站首页 android10 api level Android Camera2 简介

Android Camera2 简介

#Android Camera2 简介| 来源: 网络整理| 查看: 265

Camera2简介

在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2), 之前使用的API1(android.hardware.camera)就被标为 Deprecated 了. Camera API2相较于API1有很大不同, 并且API2是为了配合HAL3进行使用的, API2有很多API1不支持的特性, 比如:

更先进的API架构 可以获取更多的帧(预览/拍照)信息以及手动控制每一帧的参数 对Camera的控制更加完全(比如支持调整focus distance, 剪裁预览/拍照图片) 支持更多图片格式(yuv/raw)以及高速连拍 ......

上面列举的只是一部分, 并且实际功能支持情况要看HAL层是否完成了相关功能, 也就是说API有很多功能来满足拍照/录像需求, 但实际是否能用和具体设备有关.

基本架构

在API架构方面, Camera2和之前的Camera有很大区别, APP和底层Camera之前可以想象成用管道方式连接, 如下图:

38487b61-571f-4b9e-908f-acd99d69f4f1.png

如上图所示, Camera APP 通过CameraCaptureSession发送CaptureRequest, CameraDevices收到请求后返回对应数据到对应的Surface,预览数据一般都是到TextureView, 拍照数据则在ImageReader中, 整体来说就是一个请求--响应过程, 请求完成后, 可以在回调中查询到相应的请求参数和CameraDevice当前状态, 总的来说, Camera2中预览/拍照/录像数据统一由Surface来接收, CaptureRequest代表请求控制的Camera参数, CameraMetadata(CaptureResult)则表示当前返回帧中Camera使用的参数以及当前状态.

使用流程

API使用流程大体如下:

8c75b772-d214-4d2f-94ca-7b4ad877d17f.png 通过context.getSystemService(Context.CAMERA_SERVICE) 获取CameraManager. 调用CameraManager .open()方法在回调中得到CameraDevice. 通过CameraDevice.createCaptureSession() 在回调中获取CameraCaptureSession. 构建CaptureRequest, 有三种模式可选 预览/拍照/录像. 通过 CameraCaptureSession发送CaptureRequest, capture表示只发一次请求, setRepeatingRequest表示不断发送请求. 拍照数据可以在ImageReader.OnImageAvailableListener回调中获取, CaptureCallback中则可获取拍照实际的参数和Camera当前状态. 查询Camera2功能支持情况

上面说过, 不是所以手机都支持完整的Camera2功能, 现在都2018了, Camera2出来都有4年左右了, 但估计还有些中低端手机使用的HAL1, 使用HAL1就会导致Camera2一些高级功能都没法使用了, 下面讲一下如何查询设备对应Camera2的支持情况. INFO_SUPPORTED_HARDWARE_LEVEL 硬件层面支持的Camera2功能等级, 主要分为5个等级:

INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED INFO_SUPPORTED_HARDWARE_LEVEL_FULL INFO_SUPPORTED_HARDWARE_LEVEL_3 INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL

LEVEL_LEGACY: 向后兼容模式, 如果是此等级, 基本没有额外功能, HAL层大概率就是HAL1(我遇到过的都是) LEVEL_LIMITED: 有最基本的功能, 还支持一些额外的高级功能, 这些高级功能是LEVEL_FULL的子集 LEVEL_FULL: 支持对每一帧数据进行控制,还支持高速率的图片拍摄 LEVEL_3: 支持YUV后处理和Raw格式图片拍摄, 还支持额外的输出流配置 LEVEL_EXTERNAL: API28中加入的, 应该是外接的摄像头, 功能和LIMITED类似

各个等级从支持的功能多少排序为: LEGACY < LIMITED < FULL < LEVEL_3 获取代码如下:

// CameraCharacteristics 可通过 CameraManager.getCameraCharacteristics() 获取 private int isHardwareSupported(CameraCharacteristics characteristics) { Integer deviceLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL); if (deviceLevel == null) { Log.e(TAG, "can not get INFO_SUPPORTED_HARDWARE_LEVEL"); return -1; } switch (deviceLevel) { case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL: Log.w(TAG, "hardware supported level:LEVEL_FULL"); break; case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY: Log.w(TAG, "hardware supported level:LEVEL_LEGACY"); break; case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3: Log.w(TAG, "hardware supported level:LEVEL_3"); break; case CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED: Log.w(TAG, "hardware supported level:LEVEL_LIMITED"); break; } return deviceLevel; }

REQUEST_AVAILABLE_CAPABILITIES 上面讲的几个等级是从整体上说明Camera2支持情况, 我们还可以查询更多细节功能,REQUEST_AVAILABLE_CAPABILITIES 则可以知道具体支持哪些实际功能, 具体有如下功能:

BACKWARD_COMPATIBLE READ_SENSOR_SETTINGS MANUAL_SENSOR BURST_CAPTURE MANUAL_POST_PROCESSING YUV_REPROCESSING RAW DEPTH_OUTPUT PRIVATE_REPROCESSING CONSTRAINED_HIGH_SPEED_VIDEO

各个功能具体含义请参考官网的解释 :官网 的解释, 我没有深入研究. 大多数支持等级为 LEGACY 的设备, 只支持 BACKWARD_COMPATIBLE , 也就是说前面提到的Camera2新功能都不支持......

Camera2 AE/AF Region

在使用Camera2 API过程中, 设置测光和对焦区域这部分刚开始一直不知道该怎么写代码, 后面折腾了一番, 终于找到正确的方法了, 在此记录一下. AE/AF 区域需要通过用户在屏幕上的点击位置来进行设置, 因此我们要做的就是将屏幕点击点映射到底层对焦和测光位置点, 同时发送请求触发对焦这个动作. 首先要知道一点就是, 屏幕点击点坐标和Camera底层坐标不是对应的, 基本关系如下图:

AF_Coordinate.jpg

x,y坐标系表示屏幕坐标, x1,y1表示Camera对应坐标 可见屏幕点击和底层有个90度旋转关系, 实际设置AF/AE区域步骤如下:

1.首先获取SENSOR_INFO_ACTIVE_ARRAY_SIZE, 即底层Camera坐标点的范围, API中通过一个Rect表示

characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE)

得到``Rect```通常为支持的最大图片尺寸, 比如(0, 0, 4160, 3120)

2.坐标映射 我们需要将屏幕点击点映射到 SENSOR_INFO_ACTIVE_ARRAY_SIZE对应的Rect中, 从图中可以很容易看出, 坐标转换关系为 : x1 = y , y1 = previewWidth - x, 坐标转换完成后只需乘以 图片宽度/预览宽度的比例即可得到转换后的坐标, 然后以坐标点为中心生成一个矩形, 这个矩形就是我们要的结果, 实际代码片段如下:

private MeteringRectangle calcTapAreaForCamera2(CameraCharacteristics c, int areaSize, int weight) { // 获取Size Rect rect = c.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE); Log.d(TAG, "active Rect:" + rect.toString()); Rect newRect; int leftPos, topPos; // 坐标转换 float newX = currentY; float newY = previewWidth - currentX; // 大小转换 leftPos = (int) ((newX / previewHeight) * rect.right); topPos = (int) ((newY / previewWidth) * rect.bottom); // 以坐标点为中心生成一个矩形, 需要防止上下左右的值溢出 int left = clamp(leftPos - areaSize, 0, rect.right); int top = clamp(topPos - areaSize, 0, rect.bottom); int right = clamp(leftPos + areaSize, leftPos, rect.right); int bottom = clamp(topPos + areaSize, topPos, rect.bottom); newRect = new Rect(left, top, right, bottom); Log.d(TAG, newRect.toString()); // 构造MeteringRectangle return new MeteringRectangle(newRect, weight); } private int clamp(int x, int min, int max) { if (x > max) { return max; } if (x < min) { return min; } return x; }

注: 此处坐标映射可以通过Matrix进行, 熟悉Matrix的同学可以尝试下

3.设置AE/AF区域并触发对焦, 代码片段如下

public void startControlAFRequest(MeteringRectangle rect, CameraCaptureSession.CaptureCallback captureCallback) { MeteringRectangle[] rectangle = new MeteringRectangle[]{rect}; // 对焦模式必须设置为AUTO mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_AUTO); //AE mPreviewBuilder.set(CaptureRequest.CONTROL_AE_REGIONS,rectangle); //AF 此处AF和AE用的同一个rect, 实际AE矩形面积比AF稍大, 这样测光效果更好 mPreviewBuilder.set(CaptureRequest.CONTROL_AF_REGIONS,rectangle); try { // AE/AF区域设置通过setRepeatingRequest不断发请求 mSession.setRepeatingRequest(mPreviewBuilder.build(), null, mHandler); } catch (CameraAccessException e) { e.printStackTrace(); } //触发对焦 mPreviewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,CaptureRequest.CONTROL_AF_TRIGGER_START); try { //触发对焦通过capture发送请求, 因为用户点击屏幕后只需触发一次对焦 mSession.capture(mPreviewBuilder.build(), captureCallback, mHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } 总结

Camera2 API和旧的Camera API区别很大, 刚开始用可能会很不习惯, 但Camera2有很多优势, 提供了非常多的参数供我们控制, 后面API1可能会被移除, 所以可以尽早将项目用Camera2重写, 另外如果对API和HAL版本对应关系不清楚的, 可以参考我之前写的文章 Android Camera API和HAL版本对应关系. 基于Camera2 API, 我写了个Demo, 功能还算完善, 有兴趣的可以看下: Github: Camera2, 目前没有录像功能, 后续会加上.



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3